package com.bc.plugin.doc.base.impl;

import com.bc.plugin.doc.base.IRequestMappingHandler;
import com.bc.plugin.doc.dto.RequestMappingDTO;
import com.power.common.util.StringUtil;
import com.power.common.util.UrlUtil;
import com.power.doc.constants.DocAnnotationConstants;
import com.power.doc.constants.DocGlobalConstants;
import com.power.doc.utils.DocUtil;
import com.thoughtworks.qdox.model.JavaAnnotation;
import com.thoughtworks.qdox.model.JavaMethod;

import java.util.List;

/**
 * @author xhh 2019/11/21
 */
public class DefaultRequestMappingHandler implements IRequestMappingHandler {
    @Override
    public RequestMappingDTO handle(String host, String preUrl, JavaMethod method) {
        String methodType = null;
        boolean isPostMethod = false;
        int methodCounter = 0;
        String shortUrl = null;
        List<JavaAnnotation> annotations = method.getAnnotations();
        String mediaType = null;
        for (JavaAnnotation annotation : annotations) {
            String annotationName = annotation.getType().getName();
            Object produces = annotation.getNamedParameter("produces");
            if (produces != null) {
                mediaType = produces.toString();
            }
            if (DocAnnotationConstants.REQUEST_MAPPING.equals(annotationName)
                    || DocGlobalConstants.REQUEST_MAPPING_FULLY.equals(annotationName)) {
                shortUrl = DocUtil.handleMappingValue(annotation);
                Object nameParam = annotation.getNamedParameter("method");
                if (null != nameParam) {
                    methodType = nameParam.toString();
                    methodType = DocUtil.handleHttpMethod(methodType);
                    if ("POST".equals(methodType) || "PUT".equals(methodType)) {
                        isPostMethod = true;
                    }
                } else {
                    methodType = "GET";
                }
                methodCounter++;
            } else if (DocAnnotationConstants.GET_MAPPING.equals(annotationName)
                    || DocGlobalConstants.GET_MAPPING_FULLY.equals(annotationName)) {
                shortUrl = DocUtil.handleMappingValue(annotation);
                methodType = "GET";
                methodCounter++;
            } else if (DocAnnotationConstants.POST_MAPPING.equals(annotationName)
                    || DocGlobalConstants.POST_MAPPING_FULLY.equals(annotationName)) {
                shortUrl = DocUtil.handleMappingValue(annotation);
                methodType = "POST";
                methodCounter++;
                isPostMethod = true;
            } else if (DocAnnotationConstants.PUT_MAPPING.equals(annotationName)
                    || DocGlobalConstants.PUT_MAPPING_FULLY.equals(annotationName)) {
                shortUrl = DocUtil.handleMappingValue(annotation);
                methodType = "PUT";
                methodCounter++;
            } else if (DocAnnotationConstants.DELETE_MAPPING.equals(annotationName)
                    || DocGlobalConstants.DELETE_MAPPING_FULLY.equals(annotationName)) {
                shortUrl = DocUtil.handleMappingValue(annotation);
                methodType = "DELETE";
                methodCounter++;
            }
        }
        if (methodCounter > 0) {
            shortUrl = StringUtil.removeQuotes(shortUrl);

            String[] urls = shortUrl.split(",");
            String url;
            if (urls.length > 1) {
                url = getUrls(host + "/" + preUrl, urls);
                int length = urls[0].length();
                shortUrl = urls[0].substring(1, length);
            } else {
                url = UrlUtil.simplifyUrl(host + "/" + preUrl + "/" + shortUrl);
            }
            String mapping = ("/" + preUrl + "/" + shortUrl).replaceAll("/+", "/");
            return new RequestMappingDTO(url, mapping, methodType, mediaType, isPostMethod);
        }
        return null;
    }

    private String getUrls(String preUrl, String[] urls) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < urls.length; i++) {
            String url = preUrl + "/" + StringUtil.trimBlank(urls[i])
                    .replace("[", "").replace("]", "");
            sb.append(UrlUtil.simplifyUrl(url));
            if (i < urls.length - 1) {
                sb.append(";\t");
            }
        }
        return sb.toString();
    }
}
